package blue.global.encrypt;

import java.security.SecureRandom;

import blue.global.util.StringUtil;


/**
 * 密码加密工具类
 * 
 * @author zhengj
 * @since 1.0
 * @date 2009-1-5
 */
public class EncryptPassword
{
	private int length = 32;
	private final static int LENGTH_MD5 = 32;
	private final static int LENGTH_SHA1 = 40;
	private final static SecureRandom rand = new SecureRandom();

	// private static final Logger log = Logger.getLogger(PasswordUtil.class);

	/**
	 * 密码加密工具类，长度默认是32
	 */
	public EncryptPassword()
	{
	}

	/**
	 * 密码加密工具类
	 * 
	 * @param length 密码加密长度
	 * @throws IllegalArgumentException 当密码加密长度小于32时抛出
	 */
	public EncryptPassword(int length) throws IllegalArgumentException
	{
		if (length < 32)
			throw new IllegalArgumentException("密码加密长度不能小于32");
		this.length = length;
	}

	/**
	 * 比较密码原文与密文是否相等
	 * 
	 * @param src 密码原文
	 * @param md MD5信息摘要
	 * @return 相等返回true，否则返回false
	 * @throws throws IllegalArgumentException 密码加密长度和预设置不一致时抛出
	 */
	public boolean equalsPassword(String src, String md) throws IllegalArgumentException
	{
		if (length != md.length())
			throw new IllegalArgumentException("密码加密长度和预设置不一致");

		if (length <= LENGTH_SHA1) //小于 sha-1 算法的长度
		{
			String remd = md.substring(0, LENGTH_MD5);
			String ran = md.substring(LENGTH_MD5);
			return MessageDigestUtil.equalMD5(src + ran, remd);
		}
		else
		{
			int n = Integer.parseInt(md.substring(0, 1), 16);
			if ((n & 1) == 0) //选择 md5 加密算法
			{
				String remd = md.substring(1, LENGTH_MD5 + 1);
				String ran = md.substring(LENGTH_MD5 + 1);
				return MessageDigestUtil.equalMD5(src + ran, remd);
			}
			else //选择 sha-1 加密算法
			{
				String remd = md.substring(1, LENGTH_SHA1 + 1);
				String ran = md.substring(LENGTH_SHA1 + 1);
				return MessageDigestUtil.equalSHA1(src + ran, remd);
			}
		}
	}

	/**
	 * 取得加密字符串
	 * 
	 * @param src 原文
	 * @return 密文
	 */
	public String getEncryptPassword(String src)
	{
		StringBuilder sb = new StringBuilder();
		if (length <= LENGTH_SHA1) //小于 sha-1 算法的长度
		{
			String str = StringUtil.random(length - LENGTH_MD5);
			String md = MessageDigestUtil.getMD5(src + str);
			sb.append(md).append(str);
		}
		else
		{
			int ran = rand.nextInt(16);
			int n = length - 1 - ((ran & 1) == 0 ? LENGTH_MD5 : LENGTH_SHA1); //算出随机数的长度
			String str = StringUtil.random(n);
			String md = "";
			
			if ((ran & 1) == 0) //选择 md5 加密算法
				md = MessageDigestUtil.getMD5(src + str);
			else //选择 sha-1 加密算法
				md = MessageDigestUtil.getSHA1(src + str);
			
			sb.append(Integer.toHexString(ran)).append(md).append(str);
		}
		return sb.toString();
	}

	public int getLength()
	{
		return length;
	}
	
	public static void main(String[] args)
	{
		EncryptPassword ep = new EncryptPassword(50);
		String md = ep.getEncryptPassword("19850121");
		System.out.println(md);
		System.out.println(ep.equalsPassword("19850121", md));
	}

}
